<template>
  <div class="xlsx-viewer">
    <div v-if="loading" class="loading-message">
      <span class="loader"></span> 加载中...
    </div>
    <div v-if="sheets.length > 0" class="sheet-selector">
      <label for="sheet-select">选择工作表: </label>
      <select id="sheet-select" v-model="currentSheet" @change="loadSheetData">
        <option v-for="sheet in sheets" :key="sheet" :value="sheet">
          {{ sheet }}
        </option>
      </select>
      <span class="sheet-count">共 {{ sheets.length }} 个工作表</span>
    </div>
    <div v-if="tableData.length > 0" class="table-container">
      <div class="table-info">
        当前工作表: <strong>{{ currentSheet }}</strong> ({{ tableData.length }} 行数据)
      </div>
      <table>
        <thead>
          <tr>
            <th v-for="(header, index) in headers" :key="index">
              {{ header || `列 ${index + 1}` }}
            </th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(row, rowIndex) in tableData" :key="rowIndex">
            <td v-for="(cell, cellIndex) in row" :key="cellIndex">
              {{ cell }}
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <div v-else-if="!loading && sheets.length > 0" class="empty-message">
      当前工作表没有数据
    </div>

    <div v-if="error" class="error-message">
      <span class="error-icon">⚠️</span>
      暂无数据参数
      <!-- {{ error }} -->
    </div>
  </div>
</template>

<script>
import { ref, watch, onMounted } from 'vue';
import * as XLSX from 'xlsx';

export default {
  name: 'XlsxViewer',
  props: {
    filePath: {
      type: [String, File],
      required: true
    },
    autoLoad: {
      type: Boolean,
      default: true
    },
    isCSV: {
      type: Boolean,
      default: false
    }
  },
  setup(props) {
    const loading = ref(false);
    const sheets = ref([]);
    const currentSheet = ref('');
    const headers = ref([]);
    const tableData = ref([]);
    const error = ref('');
    const workbook = ref(null);

    const loadFile = async () => {
      loading.value = true;
      error.value = '';
      sheets.value = [];
      currentSheet.value = '';
      headers.value = [];
      tableData.value = [];

      try {
        let arrayBuffer;
        if (props.filePath instanceof File) {
          arrayBuffer = await props.filePath.arrayBuffer();
        } else {
          const response = await fetch(props.filePath);
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }
          arrayBuffer = await response.arrayBuffer();
        }

        const data = new Uint8Array(arrayBuffer);

        if (props.isCSV) {
          // 处理CSV文件
          const csvString = new TextDecoder().decode(data);
          const worksheet = XLSX.read(csvString, { type: 'string', raw: true });
          workbook.value = worksheet;
          sheets.value = ['CSV数据']; // CSV只有一个工作表
          currentSheet.value = 'CSV数据';
        } else {
          // 处理XLSX文件
          workbook.value = XLSX.read(data, { type: 'array' });
          sheets.value = workbook.value.SheetNames;
        }

        if (sheets.value.length > 0) {
          currentSheet.value = sheets.value[0];
          loadSheetData();
        }
      } catch (err) {
        error.value = '加载文件时出错: ' + err.message;
        console.error('File Viewer Error:', err);
      } finally {
        loading.value = false;
      }
    };

    const loadSheetData = () => {
      if (!workbook.value || !currentSheet.value) return;

      try {
        const worksheet = workbook.value.Sheets[currentSheet.value];
        if (!worksheet) {
          throw new Error(`工作表 ${currentSheet.value} 不存在`);
        }

        // 转换工作表数据为数组格式
        const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: '' });

        if (jsonData.length > 0) {
          // 处理可能没有标题行的情况
          headers.value = jsonData[0] || [];
          tableData.value = jsonData.slice(1).filter(row => row.length > 0);
        } else {
          headers.value = [];
          tableData.value = [];
        }
      } catch (err) {
        error.value = '加载工作表数据时出错: ' + err.message;
        console.error('File Viewer Error:', err);
      }
    };

    // 监听 filePath 变化
    watch(() => props.filePath, (newPath) => {
      if (newPath && props.autoLoad) {
        loadFile();
      }
    });

    // 监听 isCSV 变化
    watch(() => props.isCSV, () => {
      if (props.filePath && props.autoLoad) {
        loadFile();
      }
    });

    // 组件挂载时加载
    onMounted(() => {
      if (props.filePath && props.autoLoad) {
        loadFile();
      }
    });

    return {
      loading,
      sheets,
      currentSheet,
      headers,
      tableData,
      error,
      loadFile,
      loadSheetData,
    };
  },
};
</script>

<style scoped>
.xlsx-viewer {
  max-width: 100%;
  max-height: 100%;
  flex: 1;
  overflow-x: auto;
  font-family: Arial, sans-serif;
  border: 1px solid #e0e0e0;
  padding: 16px;
  background-color: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.sheet-selector {
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.sheet-selector select {
  padding: 8px 12px;
  border-radius: 4px;
  border: 1px solid #ddd;
  background-color: #fff;
  font-size: 14px;
  min-width: 150px;
}

.sheet-count {
  font-size: 13px;
  color: #666;
}

.table-container {
  /* border-collapse: collapse; */
  margin-top: 12px;
  overflow-x: auto;
  max-height: calc(100% - 57px);
  overflow-y: auto;
  border: 1px solid #eee;
  border-radius: 4px;
}

.table-info {
  position: sticky;
  top: 0;
  padding: 8px 12px;
  background-color: #f5f5f5;
  font-size: 14px;
  border-bottom: 1px solid #eee;
}

table {
  border-collapse: collapse;
  width: 100%;
  font-size: 14px;
}

th,
td {
  border: 1px solid #ddd;
  padding: 10px 12px;
  text-align: left;
  white-space: nowrap;
}

th {
  background-color: #f2f2f2;
  position: sticky;
  top: 42px;
  font-weight: 600;
}

tr:nth-child(even) {
  background-color: #f9f9f9;
}

tr:hover {
  background-color: #f0f0f0;
}

.loading-message {
  margin: 16px 0;
  color: #666;
  display: flex;
  align-items: center;
  gap: 8px;
}

.loader {
  border: 3px solid #f3f3f3;
  border-top: 3px solid #3498db;
  border-radius: 50%;
  width: 16px;
  height: 16px;
  animation: spin 1s linear infinite;
}

.empty-message {
  padding: 16px;
  text-align: center;
  color: #666;
  background-color: #f9f9f9;
  border-radius: 4px;
  margin-top: 12px;
}

.error-message {
  padding: 12px;
  background-color: #ffebee;
  color: #d32f2f;
  border-radius: 4px;
  margin-top: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}
</style>